We solve
>function f([x,y]) &= [x^2+y^2-10,x+y-1]
2 2
[y + x - 10, y + x - 1]
Euler can plot the solutions of both equations.
>plot2d(&f(x,y)[1],level=0,r=5); ... plot2d(&f(x,y)[2],level=0,add=true):
The intersections are the solutions.
To start the Newton algorithm we need the Jacobian.
>function Df([x,y]) &= jacobian(f(x,y),[x,y])
[ 2 x 2 y ]
[ ]
[ 1 1 ]
Now, there is the newton2 function, which does the iteration.
It needs to function f(v) and Df(v). That is, why we define f and Df with f([x,y]) and Df([x,y]). Those functions can be used with vectors or two elements.
>newton2("f","Df",[-3,3])
[-1.67945, 2.67945]
We want to simulate the Newton iteration step by step. So we define the iterating function.
>function fiter ([x,y]) &= [x,y]-invert(Df(x,y)).f(x,y)
[ 2 2 ]
[ - y - x + 10 2 y (y + x - 1) ]
[ -------------- + --------------- + x ]
[ 2 x - 2 y 2 x - 2 y ]
[ ]
[ 2 2 ]
[ y + x - 10 2 x (y + x - 1) ]
[ ------------ - --------------- + y ]
[ 2 x - 2 y 2 x - 2 y ]
>&factor(fiter(x,y))
[ 2 2 ]
[ - y + 2 y - x - 10 ]
[ -------------------- ]
[ 2 (y - x) ]
[ ]
[ 2 2 ]
[ y + x - 2 x + 10 ]
[ ------------------ ]
[ 2 (y - x) ]
Maxima returns a column vector. We need a row vector as input and output. So we define an iteration function g.
>function g(v) := fiter(v)'
Then we can iterate using the iterate() function.
>iterate("g",[-3.2,3],10)
-3.2 3
-1.87419 2.87419
-1.68744 2.68744
-1.67946 2.67946
-1.67945 2.67945
-1.67945 2.67945
-1.67945 2.67945
-1.67945 2.67945
-1.67945 2.67945
-1.67945 2.67945
-1.67945 2.67945
Another starting point yields the other solution.
>iterate("g",[1,-2],10)
1 -2
3.16667 -2.16667
2.72396 -1.72396
2.67989 -1.67989
2.67945 -1.67945
2.67945 -1.67945
2.67945 -1.67945
2.67945 -1.67945
2.67945 -1.67945
2.67945 -1.67945
2.67945 -1.67945
Of course, we can also solve this example symbolically.
>&solve(f(x,y)), %()
1 - sqrt(19) sqrt(19) + 1
[[y = ------------, x = ------------],
2 2
sqrt(19) + 1 1 - sqrt(19)
[y = ------------, x = ------------]]
2 2
[-1.67945, 2.67945, 2.67945, -1.67945]
There is also the Broyden algorithm, which does not need the derivative. It is a generalization of the Secant algorithm for more then one variable.
>broyden("f",[-3,2])
[-1.67945, 2.67945]
With the interval Newton method, we even get a proved inclusion of the zero.
>inewton2("f","Df",[-3,1])
[ ~-1.679449471770339,-1.679449471770335~, ~2.679449471770335,2.679449471770338~ ]